home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / lib / python2.5 / _strptime.pyc (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-29  |  15KB  |  409 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.5)
  3.  
  4. '''Strptime-related classes and functions.
  5.  
  6. CLASSES:
  7.     LocaleTime -- Discovers and stores locale-specific time information
  8.     TimeRE -- Creates regexes for pattern matching a string of text containing
  9.                 time information
  10.  
  11. FUNCTIONS:
  12.     _getlang -- Figure out what language is being used for the locale
  13.     strptime -- Calculates the time struct represented by the passed-in string
  14.  
  15. '''
  16. import time
  17. import locale
  18. import calendar
  19. from re import compile as re_compile
  20. from re import IGNORECASE
  21. from re import escape as re_escape
  22. from datetime import date as datetime_date
  23.  
  24. try:
  25.     from thread import allocate_lock as _thread_allocate_lock
  26. except:
  27.     from dummy_thread import allocate_lock as _thread_allocate_lock
  28.  
  29. __author__ = 'Brett Cannon'
  30. __email__ = 'brett@python.org'
  31. __all__ = [
  32.     'strptime']
  33.  
  34. def _getlang():
  35.     return locale.getlocale(locale.LC_TIME)
  36.  
  37.  
  38. class LocaleTime(object):
  39.     '''Stores and handles locale-specific information related to time.
  40.  
  41.     ATTRIBUTES:
  42.         f_weekday -- full weekday names (7-item list)
  43.         a_weekday -- abbreviated weekday names (7-item list)
  44.         f_month -- full month names (13-item list; dummy value in [0], which
  45.                     is added by code)
  46.         a_month -- abbreviated month names (13-item list, dummy value in
  47.                     [0], which is added by code)
  48.         am_pm -- AM/PM representation (2-item list)
  49.         LC_date_time -- format string for date/time representation (string)
  50.         LC_date -- format string for date representation (string)
  51.         LC_time -- format string for time representation (string)
  52.         timezone -- daylight- and non-daylight-savings timezone representation
  53.                     (2-item list of sets)
  54.         lang -- Language used by instance (2-item tuple)
  55.     '''
  56.     
  57.     def __init__(self):
  58.         '''Set all attributes.
  59.  
  60.         Order of methods called matters for dependency reasons.
  61.  
  62.         The locale language is set at the offset and then checked again before
  63.         exiting.  This is to make sure that the attributes were not set with a
  64.         mix of information from more than one locale.  This would most likely
  65.         happen when using threads where one thread calls a locale-dependent
  66.         function while another thread changes the locale while the function in
  67.         the other thread is still running.  Proper coding would call for
  68.         locks to prevent changing the locale while locale-dependent code is
  69.         running.  The check here is done in case someone does not think about
  70.         doing this.
  71.  
  72.         Only other possible issue is if someone changed the timezone and did
  73.         not call tz.tzset .  That is an issue for the programmer, though,
  74.         since changing the timezone is worthless without that call.
  75.  
  76.         '''
  77.         self.lang = _getlang()
  78.         self._LocaleTime__calc_weekday()
  79.         self._LocaleTime__calc_month()
  80.         self._LocaleTime__calc_am_pm()
  81.         self._LocaleTime__calc_timezone()
  82.         self._LocaleTime__calc_date_time()
  83.         if _getlang() != self.lang:
  84.             raise ValueError('locale changed during initialization')
  85.         
  86.  
  87.     
  88.     def __pad(self, seq, front):
  89.         seq = list(seq)
  90.         if front:
  91.             seq.insert(0, '')
  92.         else:
  93.             seq.append('')
  94.         return seq
  95.  
  96.     
  97.     def __calc_weekday(self):
  98.         a_weekday = [ calendar.day_abbr[i].lower() for i in range(7) ]
  99.         f_weekday = [ calendar.day_name[i].lower() for i in range(7) ]
  100.         self.a_weekday = a_weekday
  101.         self.f_weekday = f_weekday
  102.  
  103.     
  104.     def __calc_month(self):
  105.         a_month = [ calendar.month_abbr[i].lower() for i in range(13) ]
  106.         f_month = [ calendar.month_name[i].lower() for i in range(13) ]
  107.         self.a_month = a_month
  108.         self.f_month = f_month
  109.  
  110.     
  111.     def __calc_am_pm(self):
  112.         am_pm = []
  113.         for hour in (1, 22):
  114.             time_tuple = time.struct_time((1999, 3, 17, hour, 44, 55, 2, 76, 0))
  115.             am_pm.append(time.strftime('%p', time_tuple).lower())
  116.         
  117.         self.am_pm = am_pm
  118.  
  119.     
  120.     def __calc_date_time(self):
  121.         time_tuple = time.struct_time((1999, 3, 17, 22, 44, 55, 2, 76, 0))
  122.         date_time = [
  123.             None,
  124.             None,
  125.             None]
  126.         date_time[0] = time.strftime('%c', time_tuple).lower()
  127.         date_time[1] = time.strftime('%x', time_tuple).lower()
  128.         date_time[2] = time.strftime('%X', time_tuple).lower()
  129.         replacement_pairs = [
  130.             ('%', '%%'),
  131.             (self.f_weekday[2], '%A'),
  132.             (self.f_month[3], '%B'),
  133.             (self.a_weekday[2], '%a'),
  134.             (self.a_month[3], '%b'),
  135.             (self.am_pm[1], '%p'),
  136.             ('1999', '%Y'),
  137.             ('99', '%y'),
  138.             ('22', '%H'),
  139.             ('44', '%M'),
  140.             ('55', '%S'),
  141.             ('76', '%j'),
  142.             ('17', '%d'),
  143.             ('03', '%m'),
  144.             ('3', '%m'),
  145.             ('2', '%w'),
  146.             ('10', '%I')]
  147.         []([ (tz, '%Z') for tz_values in self.timezone for tz in tz_values ])
  148.         for offset, directive in ((0, '%c'), (1, '%x'), (2, '%X')):
  149.             current_format = date_time[offset]
  150.             for old, new in replacement_pairs:
  151.                 if old:
  152.                     current_format = current_format.replace(old, new)
  153.                     continue
  154.                 []
  155.             
  156.             time_tuple = time.struct_time((1999, 1, 3, 1, 1, 1, 6, 3, 0))
  157.             if '00' in time.strftime(directive, time_tuple):
  158.                 U_W = '%W'
  159.             else:
  160.                 U_W = '%U'
  161.             date_time[offset] = current_format.replace('11', U_W)
  162.         
  163.         self.LC_date_time = date_time[0]
  164.         self.LC_date = date_time[1]
  165.         self.LC_time = date_time[2]
  166.  
  167.     
  168.     def __calc_timezone(self):
  169.         
  170.         try:
  171.             time.tzset()
  172.         except AttributeError:
  173.             pass
  174.  
  175.         no_saving = frozenset([
  176.             'utc',
  177.             'gmt',
  178.             time.tzname[0].lower()])
  179.         if time.daylight:
  180.             has_saving = frozenset([
  181.                 time.tzname[1].lower()])
  182.         else:
  183.             has_saving = frozenset()
  184.         self.timezone = (no_saving, has_saving)
  185.  
  186.  
  187.  
  188. class TimeRE(dict):
  189.     '''Handle conversion from format directives to regexes.'''
  190.     
  191.     def __init__(self, locale_time = None):
  192.         '''Create keys/values.
  193.  
  194.         Order of execution is important for dependency reasons.
  195.  
  196.         '''
  197.         if locale_time:
  198.             self.locale_time = locale_time
  199.         else:
  200.             self.locale_time = LocaleTime()
  201.         base = super(TimeRE, self)
  202.         base.__init__({
  203.             'd': '(?P<d>3[0-1]|[1-2]\\d|0[1-9]|[1-9]| [1-9])',
  204.             'H': '(?P<H>2[0-3]|[0-1]\\d|\\d)',
  205.             'I': '(?P<I>1[0-2]|0[1-9]|[1-9])',
  206.             'j': '(?P<j>36[0-6]|3[0-5]\\d|[1-2]\\d\\d|0[1-9]\\d|00[1-9]|[1-9]\\d|0[1-9]|[1-9])',
  207.             'm': '(?P<m>1[0-2]|0[1-9]|[1-9])',
  208.             'M': '(?P<M>[0-5]\\d|\\d)',
  209.             'S': '(?P<S>6[0-1]|[0-5]\\d|\\d)',
  210.             'U': '(?P<U>5[0-3]|[0-4]\\d|\\d)',
  211.             'w': '(?P<w>[0-6])',
  212.             'y': '(?P<y>\\d\\d)',
  213.             'Y': '(?P<Y>\\d\\d\\d\\d)',
  214.             'A': self._TimeRE__seqToRE(self.locale_time.f_weekday, 'A'),
  215.             'a': self._TimeRE__seqToRE(self.locale_time.a_weekday, 'a'),
  216.             'B': self._TimeRE__seqToRE(self.locale_time.f_month[1:], 'B'),
  217.             'b': self._TimeRE__seqToRE(self.locale_time.a_month[1:], 'b'),
  218.             'p': self._TimeRE__seqToRE(self.locale_time.am_pm, 'p'),
  219.             'Z': self._TimeRE__seqToRE((lambda .0: for tz_names in .0:
  220. for tz in tz_names:
  221. tz)(self.locale_time.timezone), 'Z'),
  222.             '%': '%' })
  223.         base.__setitem__('W', base.__getitem__('U').replace('U', 'W'))
  224.         base.__setitem__('c', self.pattern(self.locale_time.LC_date_time))
  225.         base.__setitem__('x', self.pattern(self.locale_time.LC_date))
  226.         base.__setitem__('X', self.pattern(self.locale_time.LC_time))
  227.  
  228.     
  229.     def __seqToRE(self, to_convert, directive):
  230.         """Convert a list to a regex string for matching a directive.
  231.  
  232.         Want possible matching values to be from longest to shortest.  This
  233.         prevents the possibility of a match occuring for a value that also
  234.         a substring of a larger value that should have matched (e.g., 'abc'
  235.         matching when 'abcdef' should have been the match).
  236.  
  237.         """
  238.         to_convert = sorted(to_convert, key = len, reverse = True)
  239.         for value in to_convert:
  240.             if value != '':
  241.                 break
  242.                 continue
  243.         else:
  244.             return ''
  245.         regex = '|'.join((lambda .0: for stuff in .0:
  246. re_escape(stuff))(to_convert))
  247.         regex = '(?P<%s>%s' % (directive, regex)
  248.         return '%s)' % regex
  249.  
  250.     
  251.     def pattern(self, format):
  252.         '''Return regex pattern for the format string.
  253.  
  254.         Need to make sure that any characters that might be interpreted as
  255.         regex syntax are escaped.
  256.  
  257.         '''
  258.         processed_format = ''
  259.         regex_chars = re_compile('([\\\\.^$*+?\\(\\){}\\[\\]|])')
  260.         format = regex_chars.sub('\\\\\\1', format)
  261.         whitespace_replacement = re_compile('\\s+')
  262.         format = whitespace_replacement.sub('\\s+', format)
  263.         while '%' in format:
  264.             directive_index = format.index('%') + 1
  265.             processed_format = '%s%s%s' % (processed_format, format[:directive_index - 1], self[format[directive_index]])
  266.             format = format[directive_index + 1:]
  267.         return '%s%s' % (processed_format, format)
  268.  
  269.     
  270.     def compile(self, format):
  271.         '''Return a compiled re object for the format string.'''
  272.         return re_compile(self.pattern(format), IGNORECASE)
  273.  
  274.  
  275. _cache_lock = _thread_allocate_lock()
  276. _TimeRE_cache = TimeRE()
  277. _CACHE_MAX_SIZE = 5
  278. _regex_cache = { }
  279.  
  280. def _calc_julian_from_U_or_W(year, week_of_year, day_of_week, week_starts_Mon):
  281.     '''Calculate the Julian day based on the year, week of the year, and day of
  282.     the week, with week_start_day representing whether the week of the year
  283.     assumes the week starts on Sunday or Monday (6 or 0).'''
  284.     first_weekday = datetime_date(year, 1, 1).weekday()
  285.     if not week_starts_Mon:
  286.         first_weekday = (first_weekday + 1) % 7
  287.         day_of_week = (day_of_week + 1) % 7
  288.     
  289.     week_0_length = (7 - first_weekday) % 7
  290.     if week_of_year == 0:
  291.         return 1 + day_of_week - first_weekday
  292.     else:
  293.         days_to_week = week_0_length + 7 * (week_of_year - 1)
  294.         return 1 + days_to_week + day_of_week
  295.  
  296.  
  297. def strptime(data_string, format = '%a %b %d %H:%M:%S %Y'):
  298.     '''Return a time struct based on the input string and the format string.'''
  299.     global _TimeRE_cache
  300.     _cache_lock.acquire()
  301.     
  302.     try:
  303.         if _getlang() != _TimeRE_cache.locale_time.lang:
  304.             _TimeRE_cache = TimeRE()
  305.             _regex_cache.clear()
  306.         
  307.         if len(_regex_cache) > _CACHE_MAX_SIZE:
  308.             _regex_cache.clear()
  309.         
  310.         locale_time = _TimeRE_cache.locale_time
  311.         format_regex = _regex_cache.get(format)
  312.         if not format_regex:
  313.             
  314.             try:
  315.                 format_regex = _TimeRE_cache.compile(format)
  316.             except KeyError:
  317.                 err = None
  318.                 bad_directive = err.args[0]
  319.                 if bad_directive == '\\':
  320.                     bad_directive = '%'
  321.                 
  322.                 del err
  323.                 raise ValueError("'%s' is a bad directive in format '%s'" % (bad_directive, format))
  324.             except IndexError:
  325.                 raise ValueError("stray %% in format '%s'" % format)
  326.  
  327.             _regex_cache[format] = format_regex
  328.     finally:
  329.         _cache_lock.release()
  330.  
  331.     found = format_regex.match(data_string)
  332.     if not found:
  333.         raise ValueError('time data did not match format:  data=%s  fmt=%s' % (data_string, format))
  334.     
  335.     if len(data_string) != found.end():
  336.         raise ValueError('unconverted data remains: %s' % data_string[found.end():])
  337.     
  338.     year = 1900
  339.     month = day = 1
  340.     hour = minute = second = 0
  341.     tz = -1
  342.     week_of_year = -1
  343.     week_of_year_start = -1
  344.     weekday = julian = -1
  345.     found_dict = found.groupdict()
  346.     for group_key in found_dict.iterkeys():
  347.         if group_key == 'y':
  348.             year = int(found_dict['y'])
  349.             if year <= 68:
  350.                 year += 2000
  351.             else:
  352.                 year += 1900
  353.         year <= 68
  354.         if group_key == 'Y':
  355.             year = int(found_dict['Y'])
  356.             continue
  357.         if group_key == 'm':
  358.             month = int(found_dict['m'])
  359.             continue
  360.         if group_key == 'B':
  361.             month = locale_time.f_month.index(found_dict['B'].lower())
  362.             continue
  363.         if group_key == 'b':
  364.             month = locale_time.a_month.index(found_dict['b'].lower())
  365.             continue
  366.         if group_key == 'd':
  367.             day = int(found_dict['d'])
  368.             continue
  369.         None if group_key == 'H' else ampm in ('', locale_time.am_pm[0])
  370.         if group_key == 'M':
  371.             minute = int(found_dict['M'])
  372.             continue
  373.         if group_key == 'S':
  374.             second = int(found_dict['S'])
  375.             continue
  376.         if group_key == 'A':
  377.             weekday = locale_time.f_weekday.index(found_dict['A'].lower())
  378.             continue
  379.         None if group_key == 'a' else weekday == 0
  380.         None if group_key == 'j' else group_key == 'U'
  381.         if group_key == 'Z':
  382.             found_zone = found_dict['Z'].lower()
  383.             for value, tz_values in enumerate(locale_time.timezone):
  384.                 if found_zone in tz_values:
  385.                     if time.tzname[0] == time.tzname[1] and time.daylight and found_zone not in ('utc', 'gmt'):
  386.                         break
  387.                     else:
  388.                         tz = value
  389.                         break
  390.                 found_zone not in ('utc', 'gmt')
  391.             
  392.     
  393.     if julian == -1 and week_of_year != -1 and weekday != -1:
  394.         week_starts_Mon = None if week_of_year_start == 0 else False
  395.         julian = _calc_julian_from_U_or_W(year, week_of_year, weekday, week_starts_Mon)
  396.     
  397.     if julian == -1:
  398.         julian = (datetime_date(year, month, day).toordinal() - datetime_date(year, 1, 1).toordinal()) + 1
  399.     else:
  400.         datetime_result = datetime_date.fromordinal((julian - 1) + datetime_date(year, 1, 1).toordinal())
  401.         year = datetime_result.year
  402.         month = datetime_result.month
  403.         day = datetime_result.day
  404.     if weekday == -1:
  405.         weekday = datetime_date(year, month, day).weekday()
  406.     
  407.     return time.struct_time((year, month, day, hour, minute, second, weekday, julian, tz))
  408.  
  409.